<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script>
        //【1】概念解释：js是静态作用域，也就是词法作用域。反义词是动态作用域
        //静态作用域的概念是：作用域完全取决于变量声明时候的位置，而不是执行时候的位置。

        // 举例子说明：
        var value = 1;

        function foo() {
            console.log(value);
        }

        function bar() {
            var value = 2;
            foo();
        }

        bar(); // 结果是 1
        // 假设JavaScript采用静态作用域，让我们分析下执行过程：

        // 执行 foo 函数，先从 foo 函数内部查找是否有局部变量 value，如果没有，
        // 就根据书写的位置，查找上面一层的代码，也就是 value 等于 1，所以结果会打印 1。

        // 假设JavaScript采用动态作用域，让我们分析下执行过程：

        // 执行 foo 函数，依然是从 foo 函数内部查找是否有局部变量 value。如果没有，
        // 就从调用函数的作用域，也就是 bar 函数内部查找 value 变量，所以结果会打印 2。

        // 前面我们已经说了，JavaScript采用的是静态作用域，所以这个例子的结果是 1。
        // 【2】动态作用域
        // 也许你会好奇什么语言是动态作用域？

        // bash 就是动态作用域，不信的话，把下面的脚本存成例如 scope.bash，然后进入相应的目录，
        // 用命令行执行 bash ./scope.bash，看看打印的值是多少。

        value = 1

        function foo() {
            echo $value;
        }

        function bar() {
            local value = 2;
            foo;
        }
        bar
        // 这个文件也可以在 Github 博客仓库中找到。
        // 【3】思考题
        // 最后，让我们看一个《JavaScript权威指南》中的例子：
        // 案例1
        var scope = "global scope";

        function checkscope() {
            var scope = "local scope";

            function f() {
                return scope;
            }
            return f();
        }
        checkscope();
        // 案例2
        var scope = "global scope";

        function checkscope() {
            var scope = "local scope";

            function f() {
                return scope;
            }
            return f;
        }
        checkscope()();
        // 猜猜两段代码各自的执行结果是多少？【答案：两段代码都会打印：local scope。】

        // 而引用《JavaScript权威指南》的回答就是：
        // JavaScript 函数的执行用到了作用域链，这个作用域链是在函数定义的时候创建的。嵌套的函数 f() 定义在
        // 这个作用域链里，其中的变量 scope 一定是局部变量，不管何时何地执行函数 f()，这种绑定在执行 f() 时依然有效。

        // 但是在这里真正想让大家思考的是：
        // 虽然两段代码执行的结果一样，但是两段代码究竟有哪些不同呢？

        // 如果要回答这个问题，就要牵涉到很多的内容，词法作用域只是其中的一小部分，让我们期待下一篇文章
        // ————《JavaScript深入之执行上下文栈》。
    </script>
</body>

</html>